<template>
    <tnxel-submit-form ref="form" :model="model" :rules="rules">
        <el-form-item label="作为查询条件字段">
            <el-switch v-model="enabled"/>
        </el-form-item>
        <template v-if="enabled">
            <el-form-item label="参与关键字搜索" prop="keywordInvolved" v-if="keywordEnabled">
                <el-switch v-model="model.keywordInvolved"/>
                <span class="form-item-tip">是否作为关键字搜索时的条件之一</span>
            </el-form-item>
            <template v-if="!keywordEnabled || !model.keywordInvolved">
                <el-form-item label="定义名称" prop="name" class="new-error-line">
                    <tnxel-select v-model="nameDefault"
                        :items="defaultNameItems"
                        selector="radio"
                    >
                        <template #option="{item}">
                            <span class="me-1">{{ item.text }}</span>
                            <span class="text-placeholder" v-if="item.value">({{ defaultName }})</span>
                        </template>
                    </tnxel-select>
                    <el-input ref="name"
                        v-model="model.name"
                        v-if="!nameDefault"/>
                    <div class="form-item-tip">查询模型代码中的属性名</div>
                </el-form-item>
                <el-form-item label="字段类型" prop="typeId" class="new-error-line">
                    <tnxel-select class="me-2"
                        v-model="typeIdDefault"
                        :items="defaultTypeIdItems"
                        selector="radio"
                    >
                        <template #option="{item}">
                            <div class="flex-v-center">
                                <div class="me-1">{{ item.text }}</div>
                                <div class="flex-v-center text-placeholder" v-if="item.value">
                                    <div>(</div>
                                    <div :title="defaultType.getName()">{{ defaultType.simpleName }}</div>
                                    <GenericTypeSpecify v-model="row.genericTypes"
                                        :app="app"
                                        :logic-type="row.typeId"
                                        :updatable="false"
                                    />
                                    <div v-if="row.arrayed">[]</div>
                                    <div>)</div>
                                </div>
                            </div>
                        </template>
                    </tnxel-select>
                    <div class="flex-v-center flex-wrap" v-if="!typeIdDefault">
                        <LogicTypeSelect v-model="model.typeId" :app="app" :kind="clazz.kind"/>
                        <GenericTypeSpecify v-model="model.genericTypes" :app="app" :logic-type="model.typeId"/>
                        <ArrayedSelect v-model="model.arrayed"
                            class="ms-2"
                            :property="row"
                            show-if-updatable
                            title="是否数组"
                        />
                    </div>
                    <div class="form-item-tip">查询模型代码中的属性类型</div>
                </el-form-item>
                <el-form-item label="显示名称" prop="caption" class="new-error-line">
                    <tnxel-select v-model="captionDefault"
                        :items="defaultCaptionItems"
                        selector="radio"
                    >
                        <template #option="{item}">
                            <span class="me-1">{{ item.text }}</span>
                            <span class="text-placeholder" v-if="item.value">({{ this.row.caption }})</span>
                        </template>
                    </tnxel-select>
                    <el-input ref="caption"
                        v-model="model.caption"
                        v-if="!captionDefault"/>
                    <div class="form-item-tip">显示在查询条件界面中的名称</div>
                </el-form-item>
                <el-form-item label="模糊查询" prop="fuzzy" v-if="fuzzyEnabled">
                    <tnxel-enum-select v-model="model.fuzzy" type="Boolean" selector="radio"/>
                    <div class="form-item-tip">生成查询条件时，是：使用like，否：使用=</div>
                </el-form-item>
            </template>
        </template>
    </tnxel-submit-form>
</template>

<script>
import ModelingApp from '@/logic/modeling/entity/ModelingApp.js';
import EntityClass from '@/logic/modeling/entity/EntityClass.js';
import {STRING_CLASS_NAME} from '@/logic/modeling/util/dependency-lib-jdk.js';

import LogicTypeSelect from './components/LogicTypeSelect.vue';
import GenericTypeSpecify from './components/GenericTypeSpecify.vue';
import ArrayedSelect from './components/ArrayedSelect.vue';

export default {
    components: {LogicTypeSelect, GenericTypeSpecify, ArrayedSelect,},
    props: {
        app: {
            type: ModelingApp,
            required: true,
        },
        clazz: {
            type: EntityClass,
            required: true,
        },
        row: {
            type: Object,
            required: true,
        },
        after: Function,
    },
    data() {
        let querying = this.row.mappingQuerying;
        let genericTypes = null;
        if (querying?.genericTypes) {
            genericTypes = querying.genericTypes.map(genericType => genericType.clone());
        }
        return {
            enabled: !!querying,
            nameDefault: !querying || !querying.name,
            typeIdDefault: !querying || !querying.typeId,
            arrayedDefault: !querying || !querying.arrayed,
            captionDefault: !querying || !querying.caption,
            model: {
                id: querying?.id || '',
                name: querying?.name || '',
                typeId: querying?.typeId || '',
                genericTypes: genericTypes,
                arrayed: typeof querying?.arrayed === 'boolean' ? querying.arrayed : null,
                caption: querying?.caption || '',
                keywordInvolved: querying?.keywordInvolved
                    || this.clazz.keywordMappingIds.includes(this.row.mappingId),
                fuzzy: querying?.fuzzy || false,
            },
        };
    },
    computed: {
        defaultName() {
            let name = this.row.name;
            let type = this.app.findClass(this.row.typeId, true, true);
            if (type && type.kind.supports('association')) {
                let primaryPropertyName = this.app.getPrimaryLogicNames(type)[0];
                name += primaryPropertyName.firstToUpperCase();
            }
            if (this.row.parentPropertyName) {
                name = this.row.parentPropertyName + name.firstToUpperCase();
            }
            return name;
        },
        defaultType() {
            let type = this.app.findClass(this.row.typeId, true, true);
            if (type && type.kind.supports('association')) {
                let primaryLogicTypeId = this.app.getPrimaryLogicTypeIds(type)[0];
                return this.app.findClass(primaryLogicTypeId, true, true);
            }
            return type;
        },
        defaultNameItems() {
            return [{
                value: true,
                text: '默认',
            }, {
                value: false,
                text: '自定义',
            }];
        },
        defaultTypeIdItems() {
            return [{
                value: true,
                text: '默认',
            }, {
                value: false,
                text: '自定义',
            }];
        },
        defaultCaptionItems() {
            return [{
                value: true,
                text: '默认',
            }, {
                value: false,
                text: '自定义',
            }];
        },
        rules() {
            let rules = {};
            if (this.enabled) {
                if (!this.nameDefault) {
                    rules.name = [tnx.app.validator.requiredRule, tnx.app.validator.symbolRule];
                }
                if (!this.typeIdDefault) {
                    rules.typeId = [tnx.app.validator.requiredRule];
                }
                if (!this.captionDefault) {
                    rules.caption = [tnx.app.validator.requiredRule, tnx.app.validator.manualInputRule];
                }
            }
            return rules;
        },
        keywordEnabled() {
            let typeId = this.model.typeId || this.row.typeId;
            return typeId === STRING_CLASS_NAME;
        },
        fuzzyEnabled() {
            return this.keywordEnabled && !this.model.keywordInvolved;
        },
    },
    watch: {
        nameDefault() {
            if (this.nameDefault) {
                this.model.name = '';
                this.$refs.form.clearValidate();
            } else {
                this.model.name = this.defaultName;
                this.$nextTick(() => {
                    this.$refs.name.select();
                });
            }
        },
        typeIdDefault() {
            if (this.typeIdDefault) {
                this.model.typeId = '';
                this.model.genericTypes = null;
                this.model.arrayed = null;
            } else {
                this.model.typeId = this.defaultType.id;
                this.model.genericTypes = this.row.genericTypes.map(genericType => genericType.clone());
                this.model.arrayed = this.row.arrayed;
            }
        },
        captionDefault() {
            if (this.captionDefault) {
                this.model.caption = '';
            } else {
                this.model.caption = this.row.caption;
                this.$nextTick(() => {
                    this.$refs.caption.select();
                });
            }
        },
    },
    methods: {
        dialog() {
            return {
                title: '查询条件字段设置',
                width: 500,
                type: 'confirm',
                click: this.toSubmit,
            }
        },
        toSubmit(yes, close) {
            if (yes) {
                this.$refs.form.toSubmit(() => {
                    let querying = null;
                    if (this.enabled) {
                        if (this.keywordEnabled && this.model.keywordInvolved) {
                            querying = {keywordInvolved: true};
                        } else {
                            querying = Object.assign({}, this.model, {keywordInvolved: false});
                            if (!this.fuzzyEnabled) {
                                querying.fuzzy = false;
                            }
                        }
                    }
                    this.after(querying);
                    close();
                });
                return false;
            }
        },
    }
}
</script>

<style lang="scss" scoped>
:deep(.logic-type-select-container) {
    width: fit-content;

    .el-cascader {
        width: 120px;
    }
}

:deep(.generic-type-specify) {
    width: fit-content;
}
</style>
